﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

/// <summary>
/// 枚举工具类
/// 提供枚举类型的常用操作，包括：
/// 1. 获取枚举描述
/// 2. 枚举值与索引转换
/// 3. 枚举标志位检查
/// </summary>
public static class EnumTools
{
    /// <summary>
    /// 获取枚举类型的描述列表
    /// </summary>
    /// <param name="value">枚举类型</param>
    /// <returns>包含所有枚举项描述的列表</returns>
    public static List<string> GetEnumDescriptionList(Type value)
    {
        var strList = new List<string>();
        var memberInfo = value.GetFields();
        foreach (var m in memberInfo)
        {
            if (m.FieldType.Name == value.Name)
            {
                var hds = m.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (hds == null || hds.Length != 1)
                    strList.Add(m.Name);
                else
                    strList.Add((hds[0] as DescriptionAttribute).Description);
            }

        }
        return strList;
    }

    /// <summary>
    /// 获取枚举类型的完整描述字符串
    /// </summary>
    /// <param name="value">枚举类型</param>
    /// <returns>格式化后的枚举描述字符串</returns>
    public static string GetEnumDescriptionString(Type value)
    {
        string strList = "说明:\n";
        var memberInfo = value.GetFields();
        foreach (var m in memberInfo)
        {
            if (m.FieldType.Name == value.Name)
            {
                var hds = m.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (hds == null || hds.Length != 1)
                    strList = strList + (int)m.GetValue(m) + "、" + m.Name + "\n";
                else
                    strList = strList + (int)m.GetValue(m) + "、" + (hds[0] as DescriptionAttribute).Description + "\n";
            }
        }
        return strList;
    }


    /// <summary>
    /// 获取枚举值在枚举类型中的索引位置
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    /// <param name="value">枚举值</param>
    /// <returns>枚举值的索引位置，未找到返回0</returns>
    public static int GetIndexByEnum<T>(Enum value)
    {
        var list = GetEnumDescriptionList(typeof(T));
        var des = GetDescription(value);
        for (int i = 0; i < list.Count; i++)
        {
            if (string.Equals(list[i], des))
            {
                return i;
            }
        }
        return 0;
    }

    /// <summary>
    /// 根据索引获取枚举值
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    /// <param name="index">索引位置</param>
    /// <returns>对应的枚举值</returns>
    public static T GetEnumByDesIndex<T>(int index)
    {
        var strList = GetEnumDescriptionList(typeof(T));
        string des = strList[index];
        return GetEnumByDes<T>(des);
    }

    /// <summary>
    /// 根据描述获取枚举值
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    /// <param name="des">枚举描述</param>
    /// <returns>对应的枚举值，未找到返回默认值</returns>
    public static T GetEnumByDes<T>(string des)
    {
        var memberInfo = typeof(T).GetFields();
        string name = "";
        foreach (var m in memberInfo)
        {
            if (m.FieldType.Name == typeof(T).Name)
            {
                var hds = m.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (hds == null || hds.Length != 1)
                {
                    name = (m.Name);
                }
                else
                {
                    name = (hds[0] as DescriptionAttribute).Description;
                }
                if (string.Equals(name, des))
                {
                    return (T)m.GetValue(m);
                }
            }

        }
        return default(T);
    }
    /// <summary>
    /// 安全地将字符串转换为枚举值（忽略大小写）
    /// </summary>
    /// <typeparam name="T">必须是枚举类型</typeparam>
    /// <param name="key">枚举名称字符串</param>
    /// <param name="defaultValue">解析失败时返回的默认值</param>
    public static T GetEnumByString<T>(string key, T defaultValue = default) where T : struct, Enum
    {
        return Enum.TryParse<T>(key, ignoreCase: true, out var result) ? result : defaultValue;
    }


    public static string GetName(this Enum value, bool nameInstead = true)
    {
        Type type = value.GetType();
        string name = Enum.GetName(type, value);
        return name;
    }
    /// <summary>
    /// 获取枚举值的描述
    /// </summary>
    /// <param name="value">枚举值</param>
    /// <param name="nameInstead">如果为true，当没有描述时返回枚举名称</param>
    /// <returns>枚举描述或名称</returns>
    public static string GetDescription(this Enum value, bool nameInstead = true)
    {
        Type type = value.GetType();
        string name = Enum.GetName(type, value);
        if (name == null)
        {
            return null;
        }

        FieldInfo field = type.GetField(name);
        DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;

        if (attribute == null && nameInstead == true)
        {
            return name;
        }
        return attribute == null ? null : attribute.Description;
    }


    /// <summary>
    /// 将枚举值转换为整型
    /// </summary>
    /// <param name="value">枚举值</param>
    /// <returns>对应的整型值</returns>
    public static int EnumValueToInt(ValueType value)
    {
        return (int)value;
    }


    /// <summary>
    /// 检查整型值是否包含指定标志位
    /// </summary>
    /// <param name="value">要检查的值</param>
    /// <param name="flag">标志位</param>
    /// <returns>如果包含标志位返回true，否则返回false</returns>
    public static bool IsFlagMask(int value, int flag)
    {
        return (value & flag) == flag;
    }
}
